﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "Vector.h"
#include "../utility/MacroTool.h"

namespace SkyEngine2d
{
	
	bool Vector2::operator!=(const Vector2& v) const
	{
		return this->x != v.x || this->y != v.y;
	}
	
	Vector2  __thiscall Vector2::operator + (const Vector2& v)const
	{
		return Vector2(this->x + v.x, this->y + v.y);
	}
	
	Vector2  __thiscall Vector2::operator  - (const Vector2 & v)const
	{
		return Vector2(this->x - v.x, this->y - v.y);
	}
	
	Vector2  __thiscall Vector2::operator/ (float v)
	{
		return Vector2(this->x / v, this->y / v);
	}
	
	
	Vector2  Vector2::operator * (float v)
	{
		return Vector2(this->x * v, this->y * v);
	}
	
	Vector2 Vector2::Zero(0, 0);
	
	Vector2 Vector2::cross(const Vector2 & v1, const Vector2 & v2)
	{
		return Vector2(v1.x * v2.y, v2.x * v1.y);
	}
	
	float Vector2::distance(const Vector2 & v1, const Vector2 & v2)
	{
		float d = (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y);
		return sqrtf(d);
	}
	
	float Vector2::dot(const Vector2 & v1, const Vector2 & v2)
	{
		return v1.x* v2.x + v1.y * v2.y;
	}
	
	
	bool Vector2::operator==(const Vector2 & v) const
	{
		return this->x == v.x && this->y == v.y;
	}
	
	Vector2::Vector2() :DirectX::XMFLOAT2(.0f, .0f)
	{
	
	}
	
	Vector2::Vector2(DirectX::XMVECTOR v)
	{
		XMStoreFloat2(this, v);
	}
	
	Vector2::Vector2(const Vector2 & v) :DirectX::XMFLOAT2(v.x, v.y)
	{
	
	}
	
	Vector2::~Vector2()
	{
	
	}
	
	Vector2::operator D2D_POINT_2F() const
	{
		D2D_POINT_2F f; f.x = x; f.y = y; return f;
	}
	
	Vector2& Vector2::operator+=(const Vector2 & rv)
	{
		this->x += rv.x;
		this->y += rv.y;
		return *this;
	}
	
	Vector2::operator DirectX::XMVECTOR() const
	{
		return XMLoadFloat2(this);
	}
	
	bool Vector3::operator==(const Vector3 & v)
	{
		USING_NS_DX
	
			XMVECTOR v1 = XMLoadFloat3(this);
		XMVECTOR v2 = XMLoadFloat3(&v);
		return XMVector3Equal(v1, v2);
	}
	
	bool Vector3::operator!=(const Vector3 & v)
	{
		USING_NS_DX
	
			XMVECTOR v1 = XMLoadFloat3(this);
		XMVECTOR v2 = XMLoadFloat3(&v);
		return XMVector3NotEqual(v1, v2);
	}
	
	Vector3 Vector3::operator+(const Vector3 & v)
	{
		USING_NS_DX
	
			using namespace DirectX;
		auto v1 = XMLoadFloat3(this);
		auto v2 = XMLoadFloat3(&v);
		Vector3 rv;
		XMStoreFloat3(&rv, XMVectorAdd(v1, v2));
		return rv;
	}
	
	Vector3 Vector3::operator-(const Vector3 & v)
	{
		USING_NS_DX
	
			auto v1 = XMLoadFloat3(this);
		auto v2 = XMLoadFloat3(&v);
		Vector3 rv;
		XMStoreFloat3(&rv, XMVectorSubtract(v1, v2));
		return rv;
	}
	
	bool Vector4::operator==(const Vector4 & v)
	{
		USING_NS_DX
	
			auto v1 = XMLoadFloat4(this);
		auto v2 = XMLoadFloat4(&v);
	
		return XMVector4Equal(v1, v2);
	}
	
	bool Vector4::operator!=(const Vector4 & v)
	{
		USING_NS_DX
	
			auto v1 = XMLoadFloat4(this);
		auto v2 = XMLoadFloat4(&v);
		return XMVector4NotEqual(v1, v2);
	}
	
	Vector4 Vector4::operator+(const Vector4 & v)
	{
		USING_NS_DX;
	
		auto v1 = XMLoadFloat4(this);
		auto v2 = XMLoadFloat4(&v);
	
		Vector4 vr;
		XMStoreFloat4(&vr, XMVectorAdd(v1, v2));
		return vr;
	}
	
	Vector4 Vector4::operator-(const Vector4 & v)
	{
		USING_NS_DX;
	
		auto v1 = XMLoadFloat4(this);
		auto v2 = XMLoadFloat4(&v);
	
		Vector4 vr;
		XMStoreFloat4(&vr, XMVectorSubtract(v1, v2));
		return vr;
	}
}
